package com.qfedu.config;

import org.apache.ibatis.cache.Cache;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;

/**
 * 自定义mybatis 二级缓存
 *
 * 1.实现Cache 接口
 * 2.创建构造方法
 */

public class RedisCache implements Cache {


//    @Autowired  无法得到 容器中的redisTemplate，因为 RedisCache 没有加入到容器中
//    private RedisTemplate redisTemplate;


    // id其实就是获取的namespace   com.qfedu.dao.StudentDao1
    //  com.qfedu.dao.StudentDao1 就是我们 存储当前接口下的二级缓存 的key 公共部分
    //  二级缓存 map  key  value
    //                select xxxxx fromxxx  +  namespace , 查询结构
    private String id;

    // 有参构造方法
    public RedisCache(String id) {
        this.id = id;
    }

    // 返回namespace
    public String getId() {
        return id;
    }

    // 将查询结果保存
    public void putObject(Object key, Object value) {

        // 就是查询sql + namespace(id)
        //  value 从数据库查询的结果集

        if (key != null){

            // 存储到redis 中  获取redisTemplate
            getRedisTemplate().opsForValue().set(key.toString(),value);

            System.out.println("将查询到的结果集保存到redis 中  key = " + key);

        }


    }

    /**
     * 从二级缓存中获取数据
     * @param key
     * @return
     */
    public Object getObject(Object key) {

      Object result = getRedisTemplate().opsForValue().get(key.toString());
        System.out.println("从二级缓存redis中获取数据   key = " + key);

        return result;
    }


    /**
     * 在二级缓存中删除对应的key
     * @param key
     * @return
     */
    public Object removeObject(Object key) {

        Boolean delete = getRedisTemplate().delete(key.toString());
        return delete;
    }

    /**
     * 清空二级换粗
     *
     * 当发生增删改是 清空二级换粗
     */
    public void clear() {

        // 获取所有含有当前 namespace公共部分的key    id=namespace
        Set keys = getRedisTemplate().keys("*" + id + "*");


        // 删除当前namespace 下所有的key
        for (Object key : keys) {
            getRedisTemplate().delete(key.toString());
        }

        System.out.println("清空当前namespace 下的数据  namespace = " + id);
    }


    /**
     * 获取当前二级缓存的 容量
     * @return
     */
    public int getSize() {

        // 获取所有含有当前 namespace公共部分的key    id=namespace
        Set keys = getRedisTemplate().keys("*" + id + "*");

        return keys.size();
    }


    /**
     * 获取读写锁
     *  多个线程可以一起读
     *  但是有一个线程写 其他的读写线程不可以一起执行
     * @return
     */
    public ReadWriteLock getReadWriteLock() {
        return null;
    }


    /**
     *通过 ApplicationContextHolder 得到容器中的 RedisTemplate
     * @return
     */
    public RedisTemplate getRedisTemplate(){

        // 得到容器上下文对象
        ApplicationContext applicationContext = ApplicationContextHolder.getApplicationContext();


        RedisTemplate redisTemplate = (RedisTemplate) applicationContext.getBean("redisTemplate");

        return  redisTemplate;
    }
}
